<?php

class Activity_Api_Activity
{
	/**
	 * @var array
	 */
	protected $_types = NULL;

	/**
	 * add new member to item
	 * @param  Database_Model_Item    $resource
	 * @param  User_Table_Model_User  $user
	 * @param  int                    $followType
	 * @return TRUE
	 */
	function addFollower($resource, $user, $followType = 2)
	{
		$table = Nuo::getTable('activity/follower');

		$table -> insertIgnore(array(
			'resource_id' => $resource -> getItemId(),
			'follower_id' => $user -> getItemId(),
			'user_id' => $user -> getId(),
			'created_at' => time(),
			'follow_type' => $followType
		));
		return TRUE;
	}

	/**
	 * @param  Database_Model_Item    $resource
	 * @param  User_Table_Model_User  $user
	 * @return TRUE
	 */
	function removeFollower($resource, $user)
	{
		$table = Nuo::getTable('activity/follower');
		$table -> delete(array(
			'resource_id=?' => $resource -> getItemId(),
			'follower_id=?' => $user -> getItemId(),
		));
		return TRUE;
	}

	/**
	 * @return array
	 */
	function _loadTypeSpecs()
	{
		$data = array();

		$table = Nuo::getTable('activity/type');
		$select = $table -> select();
		$rows = $table -> fetchAll($select);
		foreach ($rows as $row)
		{
			$data[$row -> getId()] = $row -> toArray();
		}

		$this -> _types = $data;
	}

	/**
	 * @param string $actionType
	 * @return array|NULL
	 */
	function getTypeSpec($type)
	{
		if (NULL == $this -> _types)
		{
			$this -> _loadTypeSpecs();
		}

		if (isset($this -> _types[$type]))
		{
			return $this -> _types[$type];
		}

		return NULL;
	}

	function getItemFeed($resource)
	{
		$user = Nuo::getUser();

		if ($user -> isGuest())
		{
			return 0;
		}

		$table = Nuo::getTable('activity/feed');

		$db = $table -> getAdapter();

		if (is_object($user))
		{

			// process by union or?
			$sql = <<<SQL
SELECT
stream.feed_id
FROM nuo_activity_stream AS stream
LEFT JOIN nuo_membership_member AS member1
	ON (stream.resource_id=member1.resource_id)
# friends of members
LEFT JOIN nuo_membership_member AS member2
	ON (member1.member_id=member2.resource_id)
WHERE 
	stream.resource_id=:resourceId
	AND 
	(
		stream.privacy = 0
		OR (stream.poster_id=:memberId)
		OR (stream.privacy=1 AND member1.member_id=:memberId)
		OR (stream.privacy=2 AND (member1.member_id=:memberId OR member2.member_id=:memberId))
	)
GROUP BY stream.feed_id
ORDER BY stream_id DESC
LIMIT 10
SQL;
			$sql = strtr($sql, array(
				':resourceId' => $db -> quote($resource -> getItemId(), 'string'),
				':memberId' => $db -> quote($user -> getItemId(), 'string')
			));
		}
		else
		{
			// process by union or?
			$sql = <<<SQL
SELECT
stream.feed_id
FROM nuo_activity_stream AS stream
WHERE 
	stream.resource_id=:resourceId
	AND 
	(
		stream.privacy = 0
	)
GROUP BY stream.feed_id
ORDER BY stream_id DESC
LIMIT 10
SQL;

			$sql = strtr($sql, array(':resourceId' => $db -> quote($resource -> getItemId(), 'string'), ));

		}

		$ids = $db -> fetchCol($sql);

		if (empty($ids))
		{
			return array();
		}

		$select = $table -> select() -> where('feed_id IN (?)', $ids) -> order('feed_id DESC');

		return $table -> fetchAll($select);

	}

	function getHomeFeed()
	{

		$user = Nuo::getUser();

		if (!$user -> isMember())
		{
			return null;
		}

		$table = Nuo::getTable('activity/feed');

		$db = $table -> getAdapter();

		$sql = <<<SQL
SELECT
stream.feed_id
FROM nuo_activity_stream AS stream
INNER JOIN nuo_activity_follower AS follower
	ON (follower.resource_id = stream.resource_id)
LEFT JOIN nuo_membership_member AS member1
	ON (member1.resource_id=stream.resource_id)
LEFT JOIN nuo_membership_member AS member2
	ON (member1.member_id=member2.resource_id)
WHERE 
	follower.follower_id=:memberId
	AND 
	(
		stream.privacy = 0
		OR (stream.poster_id=:memberId)
		OR (stream.privacy=1 AND member1.member_id=:memberId)
		OR (stream.privacy=2 AND (member1.member_id=:memberId OR member2.member_id=:memberId))
	)
GROUP BY stream.feed_id
ORDER BY stream_id DESC
LIMIT 10
SQL;

		$sql = strtr($sql, array(':memberId' => $db -> quote($user -> getItemId())));

		$ids = $db -> fetchCol($sql);

		if (empty($ids))
		{
			return array();
		}

		$select = $table -> select() -> where('feed_id IN (?)', $ids) -> order('feed_id DESC');

		return $table -> fetchAll($select);
	}

	/**
	 * @param  Database_Model_Item  $poster
	 * @param  Database_Model_Item  $resource
	 * @param  Database_Model_Item  $object
	 * @param  string  $type
	 * @param  array  $privacy
	 * @param  string  $message
	 * @param  array  $extra
	 * @return  bool
	 */
	function addFeed($poster, $resource, $object, $typeId, $privacy = NULL, $message = NULL, $extra = '')
	{

		if (NULL == $poster)
		{
			$poster = Nuo::getUser();
		}

		$objectId = '';

		if ($object)
		{
			$objectId = $object -> getItemId();
		}

		if (!$resource)
		{
			return NULL;
		}

		if (!$poster)
		{
			return NULL;
		}

		$resourceId = $resource -> getItemId();
		$posterId = $poster -> getItemId();

		$feedTable = Nuo::getTable('activity/feed');
		$streamTable = Nuo::getTable('activity/stream');

		$feed = $feedTable -> fetchNew();

		$feed -> poster_id = $posterId;
		$feed -> resource_id = $resourceId;

		$feed -> object_id = $objectId;

		$feed -> type_id = $typeId;

		$feed -> created_at = time();
		$feed -> message = (string)$message;

		$privacy = array_merge(array(
			'value' => 0,
			'networks' => array(),
			'lists' => array()
		), (array)$privacy);

		$privacyValue = intval($privacy['value']);

		$feed -> privacy = $privacyValue;

		if ($extra instanceof Serializable)
		{
			$feed -> extra = serialize($extra);
		}
		$feed -> save();

		if ($privacyValue < 4)
		{
			$streamTable -> insert(array(
				'feed_id' => $feed -> getId(),
				'poster_id' => $posterId,
				'type_id' => $typeId,
				'resource_id' => $resourceId,
				'privacy' => $privacyValue,
				'list_id' => 0,
				'network_id' => 0,
			));
		}
		else
		{
			if ($privacy == 4)
			{
				foreach ($privacy['lists'] as $listId)
				{
					$streamTable -> insert(array(
						'feed_id' => $feed -> getId(),
						'poster_id' => $posterId,
						'type_id' => $typeId,
						'resource_id' => $resourceId,
						'privacy' => 4,
						'list_id' => $listId,
						'network_id' => 0,
					));
				}
			}
			else
			{
				foreach ($privacy['networks'] as $networkId)
				{
					$streamTable -> insert(array(
						'feed_id' => $feed -> getId(),
						'poster_id' => $posterId,
						'resource_id' => $resourceId,
						'type_id' => $typeId,
						'privacy' => 5,
						'list_id' => 0,
						'network_id' => $networkId,
					));
				}
			}
		}

		return $feed;
	}

}
